package com.aeye.mbr.upms.rpc.service.impl.login;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.aeye.mbr.common.base.BaseResult;
import com.aeye.mbr.common.base.constants.ErrorCodeConstants;
import com.aeye.mbr.common.exception.ServiceException;
import com.aeye.mbr.common.util.MD5Util;
import com.aeye.mbr.common.util.RedisUtil;
import com.aeye.mbr.upms.client.shiro.session.UpmsSession;
import com.aeye.mbr.upms.client.shiro.session.UpmsSessionDao;
import com.aeye.mbr.upms.dao.model.UpmsSystem;
import com.aeye.mbr.upms.dao.model.UpmsUser;
import com.aeye.mbr.upms.dto.Operator;
import com.aeye.mbr.upms.rpc.api.UpmsApiService;
import com.aeye.mbr.upms.rpc.api.UpmsSystemService;
import com.aeye.mbr.upms.rpc.api.UpmsUserService;
import com.aeye.mbr.upms.rpc.api.login.OperatorLoginService;
import com.aeye.mbr.upms.server.controller.ManageController;
import com.aeye.mbr.ws.api.BaseResp;
import com.aeye.mbr.ws.api.InputData;
import com.aeye.mbr.ws.api.pt.OperatorLoginReq;
import com.aeye.mbr.ws.api.pt.OperatorLoginResp;
import com.aeye.mbr.ws.util.JSONUtils;
import com.alibaba.fastjson.JSONObject;

/**
 * 登录接口
 * @author zcb
 *
 */
@Service
@Transactional
public class OperatorLoginServiceImpl implements OperatorLoginService {
	private static Logger _log = LoggerFactory.getLogger(OperatorLoginServiceImpl.class);
	 // 全局会话key
    private final static String ZHENG_UPMS_SERVER_SESSION_ID = "zheng-upms-server-session-id";
    // 全局会话key列表
    private final static String ZHENG_UPMS_SERVER_SESSION_IDS = "zheng-upms-server-session-ids";
    // code key
    private final static String ZHENG_UPMS_SERVER_CODE = "zheng-upms-server-code";

	@Autowired
	private UpmsSystemService upmsSystemService;

	@Autowired
	private UpmsApiService upmsApiService;
	
	@Autowired
	private UpmsUserService upmsUserService;

    @Autowired
    UpmsSessionDao upmsSessionDao;
	
	@Override
	public BaseResp<OperatorLoginResp> operatorLogin(InputData inputData) {
		
		Operator o = new Operator();
		
		OperatorLoginReq req = JSONObject.parseObject(JSONUtils.toJSONString(inputData.getData()), OperatorLoginReq.class);
		
		//登录类型1: 经办人登录,默认 . 2: 姓名身份证登录.3:接入应用登录
		if ("2".equals(req.getType()))
		{
			if(StringUtils.isEmpty(req.getName()) || StringUtils.isEmpty(req.getIdCard()))
			{
				throw new ServiceException(ErrorCodeConstants.PARAM_INCOMPLETE,"请输入姓名和身份证号码");
			}
			
			List<UpmsUser> upmsUsers = upmsUserService.selectUpmsUserByIdcard(req.getIdCard(), req.getName());
			
			if (upmsUsers!= null && upmsUsers.size()>0)
			{
				o.setUserName(upmsUsers.get(0).getUsername());
				o.setOrgCode(upmsUsers.get(0).getTopOrgId().toString());
				//金盾安全测试说pc客户端内存里面存有这个信息
				o.setPassWd(null);
				o.setAdmin(false);
				o.setContactNum(upmsUsers.get(0).getPhone());
				o.setName(upmsUsers.get(0).getRealname());
				o.setIdcard(upmsUsers.get(0).getIdcard());
				o.setCreateDate(upmsUsers.get(0).getCtime());
				
				//与设备绑定校验暂时未做，待后续看是否加上
			}else{
				throw new ServiceException(ErrorCodeConstants.OPERATOR_NOT_EXISTS);
			}
		}else
		{
			if(StringUtils.isEmpty(req.getUserId()))
			{
				throw new ServiceException(ErrorCodeConstants.PARAM_INCOMPLETE,"请输入用户名");
			}
			
			if(!"0".equals(req.getNeedPassword()) && StringUtils.isEmpty(req.getPassword()))
			{
				throw new ServiceException(ErrorCodeConstants.PARAM_INCOMPLETE,"请输入密码登录");
			}

			if("admin".equalsIgnoreCase(req.getUserId().trim()))
			{
				throw new ServiceException(ErrorCodeConstants.ADMIN_NOT_LOGIN);
			}
			UpmsUser upmsUser = upmsApiService.selectUpmsUserByUsername(req.getUserId());
			if(upmsUser == null){
				return BaseResp.error(BaseResult.fail("用户名或密码错误"));
			}
			if(!"0".equals(req.getNeedPassword()) && !upmsUser.getPassword().equals(MD5Util.MD5(req.getPassword() + upmsUser.getSalt()))){
				return BaseResp.error(BaseResult.fail("用户名或密码错误"));
			}
			
			//账号被锁定
			if(upmsUser.getLocked() == 1){
				return BaseResp.error(BaseResult.fail("此用户已被锁定"));
			}
			
			o.setUserName(upmsUser.getUsername());
			o.setOrgCode(upmsUser.getTopOrgId().toString());
			//金盾安全测试说pc客户端内存里面存有这个信息
			o.setPassWd(null);
			o.setAdmin(false);
			o.setContactNum(upmsUser.getPhone());
			o.setName(upmsUser.getRealname());
			o.setIdcard(upmsUser.getIdcard());
			o.setCreateDate(upmsUser.getCtime());
		}
		
		Session session = new UpmsSession();
		Serializable sessionId = upmsSessionDao.create(session);
		 // 更新session状态
        upmsSessionDao.updateStatus(sessionId, UpmsSession.OnlineStatus.on_line);
        // 全局会话sessionId列表，供会话管理
        RedisUtil.lpush(ZHENG_UPMS_SERVER_SESSION_IDS, sessionId.toString());
        
        // 全局会话的code
        RedisUtil.set(ZHENG_UPMS_SERVER_SESSION_ID + "_" + sessionId, o.getUserName(), (int) session.getTimeout() / 1000);
        
		//List<UpmsPermission> upmsPermissions = upmsApiService.selectUpmsPermissionByUpmsUserId(upmsUser.getUserId());
		OperatorLoginResp resp = new OperatorLoginResp();
		resp.setLastLoginTime(System.currentTimeMillis());
		resp.setSessionId(sessionId.toString());
		
		// 已注册系统
		UpmsSystem system = new UpmsSystem();
		system.setStatus((byte)1);
		List<UpmsSystem> upmsSystems = upmsSystemService.select(system);
		//暂时不做限制，让他支持所有系统，后续有要求在改造
		final List<OperatorLoginResp.SysInfo> sysList = new ArrayList<OperatorLoginResp.SysInfo>();

		for(final UpmsSystem usp:upmsSystems)
		{
			sysList.add(new OperatorLoginResp.SysInfo(){{
				setSysCode(usp.getSystemId());
				setSysName(usp.getName());
//              暂时权限这一块不返回给终端了，终端自己控制自己的权限
//				List<Privileges> lp = new ArrayList<Privileges>();
//				setPrivileges(getPrivilegesList(usp.getRoleIdList()));
			}});
		}
		
		resp.setSysList(sysList);
		
		resp.setOperator(o);
		//参数缓存版本  后续参数缓存出来后加上
		//resp.setParameterVersion(String.valueOf(CacheVersionUtils.getCacheVersion(1003).getCacheVersion()));
		
		return BaseResp.success().setRespData(resp);
	}


}